package io.github.novaframe.quartz;

import io.github.novaframe.common.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.impl.triggers.CronTriggerImpl;

import java.lang.reflect.Method;
import java.util.Date;

@Slf4j
public class QuartzJobUtil {

    /**
     * 通过反射调用scheduleJob中定义的方法
     */
    public static void invokMethod(QuartzJobModel quartzJobVM) {
        Object object = null;
        Class<?> clazz = null;
        if(StringUtils.isNotBlank(quartzJobVM.getSpringId())){
            // 按spring id查找spring bean
            object = SpringContextHolder.getBean(quartzJobVM.getSpringId());
        }else if (StringUtils.isNotBlank(quartzJobVM.getJobClass())) {//按jobClass查找
            try {
                clazz = Class.forName(quartzJobVM.getJobClass());
                object = clazz.newInstance();
            } catch (Exception e) {
                log.error("instance job class {} error: {}", quartzJobVM.getJobClass(), e.getMessage());
            }
        }

        if (object == null) {
            log.error("instance job class {} error: object is null", quartzJobVM.getJobClass());
            return;
        }

        clazz = object.getClass();
        Method method = null;
        try {
            method = clazz.getDeclaredMethod(quartzJobVM.getMethodName());
        } catch (NoSuchMethodException e) {
            log.error("no such method = {}" ,quartzJobVM.getMethodName());
        }
        if (method != null) {
            try {
                method.invoke(object);
            } catch (Exception e) {
                log.error("invoke error: {}", e.getMessage());
            }
        }
    }

    /**
     * 判断cron时间表达式正确性
     * @param cronExpression
     * @return
     */
    public static boolean isValidExpression(final String cronExpression){
        CronTriggerImpl trigger = new CronTriggerImpl();
        try {
            trigger.setCronExpression(cronExpression);
            Date date = trigger.computeFirstFireTime(null);
            return date != null && date.after(new Date());
        } catch (Exception e) {
            log.error("error: {}", e.getMessage());
        }
        return false;
    }

    /**
     * 判断Spring Bean是否存在,方法是否存在
     * @return
     */
    public static boolean isMethodExist(String springId, String methodName) {
        Object object = null;
        Class<?> clazz = null;
        boolean isExist = false;
        try{
            object = SpringContextHolder.getBean(springId);
        }catch(Exception e){
            log.error("error: ", e.getMessage());
            return isExist;
        }

        clazz = object.getClass();
        try{
            clazz.getDeclaredMethod(methodName);
        }catch(NoSuchMethodException e){
            log.error("error: ", e.getMessage());
            return isExist;
        }
        return true;
    }
}
